﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Data;
using System.Collections;
using System.IO;
using Timer = System.Windows.Threading.DispatcherTimer;

namespace Example
{
	/// <summary>
	/// Interaction logic for Window1.xaml
	/// </summary>
	public partial class Partida : Window
	{
        private SalonChat salonChatCliente;
        private TcpListener tcpListener = null; //Socket a la espera de punto remoto 
        private TcpClient tcp = null; //Socket de comunicación para el cliente
        private Thread hiloServerCliente = null; //Hilo para el servidor 
        private byte[] dataToSend = null; //Datos a enviar
        private PersonajeDAO perso = new PersonajeDAO();
        private ArrayList personajes = new ArrayList();
        private ArrayList preguntas = new ArrayList();

        private int puerto;
        private String nuevoPuerto;

        private String ipLocalAconectar;
        private int puertoAconectar;
        private ConexionPartida conexionConOponente = null;
        private Personaje mipersonaje;
        private String nombreContrincante;
        private Boolean miTurno;
        private Boolean esServidor;

        /*Conexiones auxiliares*/
        private TcpListener aux = null;
        private String direccion;

        /*Constantes codificadas*/
        /// <summary>
        /// Mensaje codificado para cerrar el juego
        /// </summary>
        private String cerrarPartida = "/CloseGame";
        /// <summary>
        /// Mensaje codificado para dar el nombre de nuestro usuario
        /// </summary>
        private String clienteNombre = "/ClientName";
        /// <summary>
        /// Mensaje codificado para obtener el nombre del adversario
        /// </summary>
        private String serverNombre = "/ServerName";
        /// <summary>
        /// Mensaje codificado para pasar turno
        /// </summary>
        private String pasarTurno = "/GiveTurn";
        /// <summary>
        /// Mensaje codificado para hacer una pregunta
        /// </summary>
        private String hacerPregunta = "/AskQuestion";
        /// <summary>
        /// Mensaje codificado para responder una pregunta
        /// </summary>
        private String enviarRespuesta = "/Answer";
        /// <summary>
        /// Mensaje codificado para adivinar el personaje del contrario
        /// </summary>
        private String adivinar = "/Guess";
        /// <summary>
        /// Mensaje codificado para señalar que ganamos
        /// </summary>
        private String victoria = "/Victory";

        /*Variables del temporizador y el turno*/
        Thread tempo = null;//Arrancamos el temporizador siempre y cuando nuestro turno sea true
        /// <summary>
        /// Tiempo de la cuenta atrás
        /// </summary>
        int tiempoTurno = 30;//Tiempo del turno en segundos


        
        /// <summary>
        /// Constructor de la partida, inicializa todo lo necesario para jugar una partida con otro cliente, aquí quien reta hace servidor
        /// </summary>
        /// <param name="direccion">Direccion de conexión para conectarnos al servidor</param>
        /// <param name="esServidor">True entonces actuamos de servidor, False actuamos de cliente</param>
        /// <param name="miNombre">Nombre del cliente en cuestión</param>
        /// <param name="salonChatCliente">Le pasamos el padre que es el salonChatCliente</param>
		public Partida(SalonChat salonChatCliente, Boolean esServidor, String direccion, String miNombre)
		{
            /*Inicializacion*/
			this.InitializeComponent();
            this.salonChatCliente = salonChatCliente;
            this.puerto = int.Parse(salonChatCliente.nuevoPuerto) + 1001;
            this.direccion = direccion;
            this.usuarioLbl.Content = miNombre;
            this.esServidor = esServidor;
            /*Temporizador variables*/

            tempo = new Thread(this.temporizador);//Inicializamos el hilo con el metodo


            //servidor
            if (esServidor)//Actua como servidor
            {
                parseaDireccion(this.direccion);
                generarPartida();
                this.miTurno = true;//Quien crea la partida tiene el turno (al principio)
                cambiarTurnoInterfaz();
                
            }
            //cliente
            else//Actua como cliente
            {
                parseaDireccion(this.direccion);
                conexionPartida();
                this.miTurno = false;//Si entramos como invitamos no tiene el turno (al principio)
                cambiarTurnoInterfaz();
            }

            DataSet ds = new DataSet("personajes");
            ds = perso.obtener_personajes();
           
            int i;
            for (i = 0; i < ds.Tables["personajes"].Rows.Count; i++)
            {
                DataRow myRow;
                myRow = ds.Tables["personajes"].Rows[i];
                Personaje aux = new Personaje((String)myRow["nombre"], (byte[])myRow["avatar1"], (byte[])myRow["avatar2"]);
                personajes.Add(aux);  
            }

            /* Rellenamos el tablero con los personajes */
            Personaje aux2;
            MemoryStream byteStream;
            BitmapImage imagen;
            ArrayList lbl = new ArrayList();
            ArrayList img = new ArrayList();
            lbl.Add(label1);
            lbl.Add(label2);
            lbl.Add(label3);
            lbl.Add(label4);
            lbl.Add(label5);
            lbl.Add(label6);
            lbl.Add(label7);
            lbl.Add(label8);
            lbl.Add(label9); 
            lbl.Add(label10); 
            lbl.Add(label11);
            lbl.Add(label12);
            lbl.Add(label13);
            lbl.Add(label14);
            lbl.Add(label15);
            img.Add(image1);
            img.Add(image2);
            img.Add(image3);
            img.Add(image4);
            img.Add(image5);
            img.Add(image6);
            img.Add(image7);
            img.Add(image8);
            img.Add(image9);
            img.Add(image10);
            img.Add(image11);
            img.Add(image12);
            img.Add(image13);
            img.Add(image14);
            img.Add(image15);

            for (i = 0; i < 15; i++)
            {
                String cadena_aux = "image" + i;
                Label lblaux = (Label)lbl[i];
                Image imgaux = (Image)img[i];
                aux2 = (Personaje)personajes[i];
                lblaux.Content = aux2.getNombre();
                byteStream = new MemoryStream(aux2.getAvatar1());
                imagen = new BitmapImage();
                imagen.BeginInit();
                imagen.StreamSource = byteStream;
                imagen.EndInit();
                imgaux.Source = imagen;
                //imgaux.Name = i.ToString();
                imgaux.Name = cadena_aux;
                comboBoxAdivinar.Items.Add(aux2.getNombre());
            }

            /* De forma aleatoria seleccionamos el personaje con el que vamos a jugar */
            Random objeto = new Random();
            int numero = objeto.Next(0, 15);
             
            mipersonaje = (Personaje) personajes[numero];
            byteStream = new MemoryStream(mipersonaje.getAvatar1());
            imagen = new BitmapImage();
            imagen.BeginInit();
            imagen.StreamSource = byteStream;
            imagen.EndInit();
            imgMiPerso.Source = imagen;
            labelMiPerso.Content = mipersonaje.getNombre();

            /* Rellenamos la lista de preguntas */
            PreguntaDAO preg = new PreguntaDAO();
            DataSet ds_preg = new DataSet("preguntas");
            ds_preg = preg.obtener_preguntas();

            for (i = 0; i < ds_preg.Tables["preguntas"].Rows.Count; i++)
            {
                DataRow myRow;
                myRow = ds_preg.Tables["preguntas"].Rows[i];
                Pregunta aux = new Pregunta((int)myRow["id"], (String)myRow["pregunta"]);
                preguntas.Add(aux);
                preguntasCombo.Items.Add((String)myRow["pregunta"]);
            }

            
		}
        /// <summary>
        /// Delegado que se encarga de modificar la interfaz en el temporizador
        /// </summary>
        /// <param name="contador">Segundos actuales del contador</param>
        private delegate void contadorDel(int contador);

        public void delegarModificarContadorInterfaz(int contador)
        {
            contadorDel aux = new contadorDel(this.modificarContadorInterfaz);
            Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, aux, contador);
        }

        /// <summary>
        /// Método que pinta en la interfaz el contador actual de la cuenta atrás
        /// </summary>
        /// <param name="contador">Segundos actuales del contador</param>
        public void modificarContadorInterfaz(int contador)
        {
            this.contadorLbl.Content = contador.ToString();
            if (contador < 10)
            {
                this.contadorLbl.Foreground = Brushes.Red;
            }
            else
            {
                this.contadorLbl.Foreground = Brushes.Green;
            }
        }

        /// <summary>
        /// Delegado que se encarga de modificar la interfaz en el turno
        /// </summary>
        private delegate void temporizadorDel();

        public void delegarCambiarTurnoInterfaz()
        {
            temporizadorDel aux = new temporizadorDel(this.cambiarTurnoInterfaz);
            Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, aux);
        }

        /// <summary>
        /// Método que se encarga de decir en la interfaz Si tenemos el turno o No
        /// </summary>
        private void cambiarTurnoInterfaz()
        {
            if (miTurno == true)
            {
                this.tengoTurnoLbl.Foreground = Brushes.Green;
                this.tengoTurnoLbl.Content = "Si";
            }
            else
            {
                this.tengoTurnoLbl.Foreground = Brushes.Red;
                this.contadorLbl.Foreground = Brushes.Red;
                this.contadorLbl.Content = "0";
                this.tengoTurnoLbl.Content = "No";
            }
        }

        /// <summary>
        /// Evento que se produce cuando se cierra la ventana de la partida, se manda un mensaje cifrado cerrando la partida al contrincante
        /// </summary>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            this.enviarMensajeCifrado(cerrarPartida);
            cerrarJuego();
        }

        /// <summary>
        /// Método que se encarga de cerrar todos los hilos y hacer que la desconexión de una partida sea limpia
        /// </summary>
        private void cerrarJuego()
        {
            //Matamos los hilos
            /*Paramos la conexion*/
            //Si somos servidor ademas paramos el escuchador de clientes
            if (esServidor)
            {
                this.tcpListener.Stop();
            }

            this.tempo.Abort();//Paramos el hilo
            this.tcp.Close();//cerramos la conexion
            this.conexionConOponente.stopThread();//Paramos el hilo parte cliente o el servidor
            this.salonChatCliente.Show();//Volvemos al salon
            this.salonChatCliente.estadoJugado = false;
            this.Hide();
        }

        /// <summary>
        /// Método que hace la conexión con el Servidor (desde el cliente)
        /// </summary>
        /// <returns>Devuelve True si la conexión fue buena, False en caso contrario</returns>
        private Boolean conexionPartida()
        {

            //Intentamos la conexion
            try
            {
                Thread.Sleep(5000);//Esperamos un delay de 5 segundos antes de realizar la conexion con el servidor
                IPAddress address = IPAddress.Parse(this.ipLocalAconectar);

                //Conectar al socket destino en espera
                tcp = new TcpClient(new IPEndPoint(IPAddress.Parse(ipLocalAconectar), puertoAconectar + 1001));
                LingerOption lingerOption = new LingerOption(false, 1);
                tcp.LingerState = lingerOption;
                // Concetarnos al puerto e ip remotos
                tcp.Connect(IPAddress.Parse(ipLocalAconectar), puertoAconectar + 1000);
                nuevoPuerto = recibirMensaje();
                tcp.Close();
                tcp = new TcpClient(new IPEndPoint(IPAddress.Parse(ipLocalAconectar), int.Parse(nuevoPuerto) + 1));
                tcp.Connect(IPAddress.Parse(ipLocalAconectar), int.Parse(nuevoPuerto));

                conexionConOponente = new ConexionPartida(this, tcp);
                enviarMensajeCifrado(clienteNombre + " " + this.usuarioLbl.Content);//El cliente le manda su nombre al server
                tempo.Start();//Cuando tenemos el turno empezamos el temporizador
                
                return true;
            }
            //Si la conexion falla por cualquier motivo retornamos un false
            catch
            {
                return false;
            }

        }


        /// <summary>
        /// Método que se encarga de generar una partida (Servidor), crea el hilo que esperará al cliente a conectarse
        /// </summary>
        public void generarPartida()
        {

            /*Generamos un hilo nuevo con una nueva sesion para los dos - El que crea la partida hace de servidor*/

            // Obtenemos el localhost
            IPHostEntry localHost = Dns.GetHostEntry(Dns.GetHostName());
            // Creamos el EndPoint en: (IpLocal + MiPuerto+1001)
            //IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(LocalIPAddress()), puerto);
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(ipLocalAconectar), puertoAconectar+1000);
            // Instanciamos el canal TCP a la escucha a parte con lo que no se queda pillada la interfaz
            tcpListener = new TcpListener(localEndPoint);
            tcpListener.Start();//Escuchamos al cliente

            // Esperamos al cliente - Actuamos como lo hace el servidor anterior
            hiloServerCliente = new Thread(this.EsperaAlOponente);
            hiloServerCliente.Start();

        }

        /// <summary>
        /// Método que parsea una direccion, y extrae el Ip y el Puerto
        /// </summary>
        /// <param name="direccion">Direccion Ip+Puerto</param>
        private void parseaDireccion(String direccion)
        {
            Boolean extrajoIp = false;

            char[] delimitador = new char[] { ':' };
            foreach (string substr in direccion.Split(delimitador))
            {
                //Extraigo la Ip
                if (!extrajoIp)
                    {
                        this.ipLocalAconectar = substr;
                        extrajoIp = true;
                    }
               //Extraigo el puerto
               else
                    {
                        this.puertoAconectar = int.Parse(substr);
                    }
            }
        }

        /// <summary>
        /// Método para obtener la Ip del Cliente
        /// </summary>
        private string LocalIPAddress()
        {
            IPHostEntry host;
            string localIP = "";
            host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily.ToString() == "InterNetwork")
                {
                    //Mediante este if descartamos las Ips erroneas
                    /*if (ip.ToString().Substring(0, 3) != "192")
                    {
                        localIP = ip.ToString();
                    }*/
                    //Descomentar en casa y comentar el If, ya que puede dar problemas
                    localIP = ip.ToString();
                }
            }
            return localIP;
        }

        /// <summary>
        /// Método que ejecuta el Servidor para escuchar al Cliente para que este se conecte, abre un Escuchador
        /// </summary>
        private void EsperaAlOponente()
        {
            Boolean oponenteEncontrado = false;
            while (!oponenteEncontrado)
            {
                Thread.Sleep(100);
                // Si existe alguna petición se acepta y se crea un objeto con la conexión
                if (tcpListener.Pending())
                {
                    try
                    {
                        int port = puerto + 2;//Nuevo puerto para el cliente
                        tcp = tcpListener.AcceptTcpClient();
                        enviarMensaje(tcp, port.ToString());//Aqui le dice al cliente que use otro puerto
                        tcp.Close(); //Cerramos y creamos nueva conexión en el nuevo puerto
                        //TcpListener aux = new TcpListener(IPAddress.Parse(LocalIPAddress()), port);
                        aux = new TcpListener(IPAddress.Parse(LocalIPAddress()), port);
                        aux.Start();
                        while (!aux.Pending()) Thread.Sleep(100);
                        TcpClient auxtcp = aux.AcceptTcpClient();
                        conexionConOponente = new ConexionPartida(this, auxtcp); //Guardamos la conexion del oponente
                        oponenteEncontrado = true;//Hemos encontrado el cliente , ya podemos matar el hilo
                        tempo.Start();//Cuando tenemos el turno empezamos el temporizador
                        
                        aux.Stop();//Paramos el tcpListener
                    }
                    catch (Exception e) { MessageBox.Show(e.ToString()); }
                }
            }
        }

        /// <summary>
        /// Método que envia un mensaje a una conexión determinada
        /// </summary>
        private void enviarMensaje(TcpClient tc, string msg)
        {
            //Prepara mensaje para enviar como array de bytes
            char[] charArray = msg.ToCharArray(0,
            msg.Length);
            dataToSend = new byte[msg.Length];
            for (int charCount = 0; charCount < msg.Length; charCount++)
            {
                dataToSend[charCount] = (byte)charArray[charCount];
            }
            //Usamos el socket para enviar el mensaje
            tc.GetStream().Write(dataToSend, 0, dataToSend.Length);
        }


        /// <summary>
        /// Delegado que se encarga de modificar la interfaz cuando se reciben mensajes por parte del adversario
        /// </summary>
        private delegate void RecibirMensajeDel(string msg);

        public void delegarRecibirMensaje(string msg)
        {
            RecibirMensajeDel aux = new RecibirMensajeDel(this.escribirMensaje);
            Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, aux, msg);
        }

        /// <summary>
        /// Método que parsea el mensaje que se recibe y se realizá una acción u otra
        /// </summary>
        /// <param name="msg">Mensaje que recibio y se parsea para su posterior tratamiento</param>
        private void escribirMensaje(string msg)
        { //Escribo en mi interfaz a través de la invocación del delegado (Cliente)

            //El oponente abandono la partida
            if (msg.Contains(cerrarPartida))
            {
                //EmergenteVentana emergenteVentana = new EmergenteVentana();
                //emergenteVentana.Title = "Ventana de información";
                //emergenteVentana.infoLbl.Content = "El oponente abandono la partida";

                //this.conexionConOponente.stopThread();
                cerrarJuego();
                this.salonChatCliente.Show();
                this.salonChatCliente.estadoJugado = false;
                this.Hide();

            }

            else if (msg.Contains(hacerPregunta))
            {
                //Tenemos que parsear el mensaje primero
                char[] delimitador = new char[] { ' ' };
                foreach (string substr in msg.Split(delimitador))
                {
                    //Si no contiene la barra y no contiene una cadena vacia
                    if (!substr.Contains("/") && substr != "")
                    {
                        String pregunta_hecha = substr;
                        /* Hacemos la consulta a la base de datos */
                        comprobarRespuesta(int.Parse(pregunta_hecha));

                    }
                }

            }

            else if (msg.Contains(enviarRespuesta))
            {
                //Tenemos que parsear el mensaje primero
                char[] delimitador = new char[] { ' ' };
                foreach (string substr in msg.Split(delimitador))
                {
                    //Si no contiene la barra y no contiene una cadena vacia
                    if (!substr.Contains("/") && substr != "")
                    {
                        String respuesta_hecha = substr;
                        /* Mostramos la respuesta en la interfaz */
                        if (respuesta_hecha == "True")
                        {
                            SolidColorBrush color = new SolidColorBrush(Colors.Green);
                            respuestaLbl.Foreground = color;
                            this.respuestaLbl.Content = "SI";
                        }
                        else
                        {
                            SolidColorBrush color = new SolidColorBrush(Colors.Red);
                            respuestaLbl.Foreground = color;
                            this.respuestaLbl.Content = "NO";
                        }


                    }
                }

            }

            else if (msg.Contains(clienteNombre))
            {//El cliente nos manda su nombre
                //Tenemos que parsear el mensaje primero
                char[] delimitador = new char[] { ' ' };
                foreach (string substr in msg.Split(delimitador))
                {
                    //Si no contiene la barra y no contiene una cadena vacia
                    if (!substr.Contains("/") && substr != "")
                    {
                        nombreContrincante = substr;//Obtendo el nombre del contrincante
                        this.oponenteLbl.Content = nombreContrincante;
                        enviarMensajeCifrado(serverNombre + " " + this.usuarioLbl.Content);//Le damos nuestro nombre
                    }
                }
            }
            else if (msg.Contains(serverNombre))
            {//El servidor nos manda su nombre
                //Tenemos que parsear el mensaje primero
                char[] delimitador = new char[] { ' ' };
                foreach (string substr in msg.Split(delimitador))
                {
                    //Si no contiene la barra y no contiene una cadena vacia
                    if (!substr.Contains("/") && substr != "")
                    {
                        nombreContrincante = substr;//Obtendo el nombre del contrincante
                        this.oponenteLbl.Content = nombreContrincante;
                    }
                }
            }

            else if (msg.Contains(adivinar))
            {//El servidor nos manda su nombre
                //Tenemos que parsear el mensaje primero
                char[] delimitador = new char[] { ' ' };
                foreach (string substr in msg.Split(delimitador))
                {
                    //Si no contiene la barra y no contiene una cadena vacia
                    if (!substr.Contains("/") && substr != "")
                    {
                        String aux_adv = substr;
                        if (mipersonaje.getNombre().Equals(substr))
                        {
                            /* Se ha adivinado el personaje */
                            Ventana vent = new Ventana(3);
                            vent.Show();
                            enviarMensajeCifrado(victoria + " " + "True");

                            this.enviarMensajeCifrado(cerrarPartida);
                        }
                        else
                        {
                            /* No se ha adivinado el personaje */
                            Ventana vent = new Ventana(4);
                            vent.Show();
                            enviarMensajeCifrado(victoria + " " + "False");
                            this.enviarMensajeCifrado(cerrarPartida);
                        }
                    }
                }
            }

            else if (msg.Contains(victoria))
            {//El servidor nos manda su nombre
                //Tenemos que parsear el mensaje primero
                char[] delimitador = new char[] { ' ' };
                foreach (string substr in msg.Split(delimitador))
                {
                    //Si no contiene la barra y no contiene una cadena vacia
                    if (!substr.Contains("/") && substr != "")
                    {
                        if (substr.Equals("True"))
                        {
                            Ventana vent = new Ventana(4);
                            vent.Show();
                            this.enviarMensajeCifrado(cerrarPartida);
                            //Cerramos la partida
                            //cerrarJuego();
                        }
                        else
                        {
                            Ventana vent = new Ventana(3);
                            vent.Show();
                            this.enviarMensajeCifrado(cerrarPartida);
                        }
                    }
                }
            }


            else if (msg.Contains(pasarTurno))
            {//Si el oponente pasa turno, ponemos nuestro turno a true y ademas le damos valor a nuestro temporizador
                this.miTurno = true;
                cambiarTurnoInterfaz();
            }
            else
            {
                Paragraph p = new Paragraph();
                p.Inlines.Add(new Run(msg));
                fdocAux.Blocks.Add(p);
            }


        }

        /// <summary>
        /// Método que comprueba la respuesta a una pregunta realizada por el contrincante, se manda la respuesta a este posteriormente
        /// </summary>
        /// <param name="id_pregunta">El identificador de la pregunta para comparar en la base de datos</param>
        private void comprobarRespuesta(int id_pregunta)
        {
            Boolean respuesta;
            respuesta = mipersonaje.dame_respuesta(id_pregunta);
            enviarMensajeCifrado(enviarRespuesta + " " + respuesta.ToString());
        }

        /// <summary>
        /// Método que convierte los Bytes en Strings cuando se reciben mensajes
        /// </summary>
        private string recibirMensaje()
        {
            int readBytes = 0;
            StringBuilder msg = new StringBuilder(SalonChat.Constants.maxNoOfBytes);
            byte[] byteNom = new byte[SalonChat.Constants.maxNoOfBytes];
            byte count1 = 0x01;
            for (int i = 0; i < byteNom.Length; i++)
                byteNom[i] = count1++;
            while (readBytes == 0)
            {
                readBytes = tcp.GetStream().Read(byteNom, 0, byteNom.Length);
                for (int i = 0; i < readBytes; i++)
                    msg.Append((char)byteNom[i]);
                Thread.Sleep(200);
            }
            string mensaje = msg.ToString();
            if (mensaje == null) mensaje = recibirMensaje();
            return mensaje;
        }

        /// <summary>
        /// Evento cuando pulsamos enviar un mensaje común por el chat privado
        /// </summary>
        private void enviarChatBtn_Click(object sender, RoutedEventArgs e)
        {
            if (this.inputBox.Text.Length != 0)
            { //Escribir mensaje en la ventana local 
                //Componemos el mensaje
                String textoMandar = this.usuarioLbl.Content + "> " + this.inputBox.Text;

                //Pintamos en nuestra pantalla
                Paragraph p = new Paragraph();
                p.Inlines.Add(new Run(textoMandar));
                fdocAux.Blocks.Add(p);


                //Mandamos el mensaje al contrincante
                this.conexionConOponente.enviarMensaje(textoMandar);
                /*Inicializamos las variables*/
                this.inputBox.Text = "";
            }
        }

        /// <summary>
        /// Método que manda un mensaje cifrado al oponente
        /// </summary>
        /// <param name="msg">Mensaje cifrado a mandar</param>
        private void enviarMensajeCifrado(String msg)
        {
                this.conexionConOponente.enviarMensaje(msg);//Mandamos el mensaje cifrado
        }

        /// <summary>
        /// Método que cambia las imagenes cuando estas son clickeadas
        /// </summary>
        private void CambiarImagen(object sender, MouseButtonEventArgs e)
        {
            Image aux = (Image)sender;
            /*  CAMBIAMOS LA IMAGEN */
            
            string split = aux.Name.Remove(0,5);
            int i = int.Parse(split);

            MemoryStream byteStream;
            BitmapImage imagen;
            Personaje aux2 = (Personaje)personajes[i];
            byteStream = new MemoryStream(aux2.getAvatar2());
            imagen = new BitmapImage();
            imagen.BeginInit();
            imagen.StreamSource = byteStream;
            imagen.EndInit();
            aux.Source = imagen;      
        }

        /// <summary>
        /// Evento que hace el tratamiento cuando pasamos el turno, manda un mensaje cifrado al otro Cliente
        /// </summary>
        private void pasarBtn_Click(object sender, RoutedEventArgs e)
        {
            //Si todavia tengo el turno entonces lo podemos pasar
            if (this.miTurno == true)
            {
                this.miTurno = false;
                cambiarTurnoInterfaz();
                enviarMensajeCifrado(pasarTurno);
            }

        }

        /// <summary>
        /// Método que realiza una pregunta al otro usuario, a través del botón de preguntar
        /// </summary>
        private void preguntaBtn_Click(object sender, RoutedEventArgs e)
        {
            //Si tengo el turno entonces puedo preguntar
            if(this.miTurno == true && this.preguntasCombo.SelectedItem!=null){
                int indice_preg = this.preguntasCombo.SelectedIndex + 1;
                this.preguntaLbl.Content = this.preguntasCombo.SelectedItem.ToString();
                this.enviarMensajeCifrado(hacerPregunta + " " + indice_preg);
                this.miTurno = false;
                cambiarTurnoInterfaz();
                enviarMensajeCifrado(pasarTurno);
                
            }
        }

        /// <summary>
        /// Método que implementa el hilo del temporizador
        /// </summary>
        private void temporizador()
        {

            do
            {
                    //Si es mi turno y aun tengo tiempo entonces el cliente continua con su actividad
                    for (int i = 0; (i < tiempoTurno) && (miTurno == true); i++)
                    {
                        this.delegarModificarContadorInterfaz(tiempoTurno - i);
                        Thread.Sleep(1000);
                    }
                    //Si sale del for es que o han pasado 20 segundos o hemos pasado el turno, sino hemos pasado el turno entonces se acabo el tiempo
                    if (miTurno == true)
                    {
                        this.miTurno = false;
                        this.delegarCambiarTurnoInterfaz();//Usando el delegado porque estamos en un hilo externo a la interfaz
                        enviarMensajeCifrado(pasarTurno);//Pasamos el turno
                    }

                    Thread.Sleep(500);
            } while (true);
        }

        /// <summary>g
        /// Evento que se produce al pulsar adivinar personaje, se comprueba si tenemos el turno y si tenemos alguna posibilidad elegido
        /// </summary>
        private void adivinarBtn_Click(object sender, RoutedEventArgs e)
        {
            if (this.miTurno && this.comboBoxAdivinar.SelectedItem!=null)
            {
                enviarMensajeCifrado(adivinar + " " + this.comboBoxAdivinar.SelectedItem.ToString());
            }
        }
	}
}